package sparrowGui
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.utils.getTimer;
	
	import sparrowGui.impl.IScrollBar;
	import sparrowGui.skin.ScrollBarSkin;
	import sparrowGui.utils.PubFun;

	/**
	 * 纵向普通滚动条
	 * 使用方法是先设置mask显示容器，再设置上下滚动的显示容器
	 * @author Pelephone
	 */	
	public class VScrollBar extends Component implements IScrollBar
	{
		// 滚动条的宽度
		public static const THICKNESS:Number 	= 14;
		public static const MIN_SLIDER_HEIGHT:int = 5;
		
/*		 垂直滚动条功能暂不开发
		public static const HORIZONTAL:String 	= "horizontal";
		public static const VERTICAL:String 	= "vertical";
		public var orientation:String = "vertical";		//定位方式,垂直或者纵向,默认是垂直滚动条*/
		
		private static const DELAY_MOVE_TIME:int = 500;	// 点击后延迟500毫秒，滚动条朝方向滚动
		
		//被分隔成N分,上下箭头每点击一次silder上下的高度
		protected var segment:Number;
		
		// 0~1之间的数,表示被盖住的显示容器与遮照容器的坐标比
		private var _value:Number = 0;
		
		//用于暂存点击时间和Y坐标
		private var _clickTime:int;		// 暂存按下时的时间，外加enterframe判断点击了多长时间
		private var _clickPosi:Number;		// 暂存点击目标的位置
		private var _mouseUpDown:int;		// 暂存鼠标按下或者是放开事件数据
		
		public function VScrollBar(argSkin:Sprite=null)
		{
			_skin = argSkin || new ScrollBarSkin();
			super();
		}
		
		override protected function init():void
		{
			addChild(skin);
			
//			upBtn.visible = false;
//			downBtn.visible = false;
//			PubFun.SafeRemoveChild(upBtn);
//			PubFun.SafeRemoveChild(downBtn);
		}
		
		/**
		 * 设置进行滚动的两显示对象，使对象1庶照对象2进行滚动
		 * @param maskDP
		 * @param contDP
		 * @param step 每点击一下箭头滚动的距离
		public function activeScroll(maskDP:DisplayObject,contDP:DisplayObject,step:Number=0):void
		{
			PubFun.alignRect(maskDP,contDP,"TL");
			contDP.mask = maskDP;
//			contDP.scrollRect = new Rectangle(maskDP.x,maskDP.y,maskDP.width,maskDP.height);
//			if(maskDP.parent) maskDP.parent.removeChild(maskDP);
			
			if(sliderDist<upBtn.height || maskDP.height>=contDP.height){
				enabled = false;
				delEvt();
			}
			else
			{
				enabled = true;
//				slider.width = THICKNESS;
				var slh:int = int(sliderDist*maskDP.height/contDP.height);
				slider.height = slh;
				if(slider.height<MIN_SLIDER_HEIGHT) slider.height = int(MIN_SLIDER_HEIGHT);
				addEvt();
				this.visible = true;
			}
			
			if(!step) segment = scrollDist/25;
			else
				segment = (sliderDist-slh)*step/(contDP.height-maskDP.height);
		}
		 */
		
		/**
		 * 通过要移动的对象的最小位置和最大位置初始激活滚动条
		 * 中间滚动块在最左边的时间value是min,最右边时value是max
		 * @param min 		滚动条value为0时对应容器的最小位置,Vlist的maskDP.height
		 * @param max 		滚动条value为1时对应容器的最大位置,Vlist的contDP.height
		 * @param stepValue 每点一次滚动率
		 */
		public function setSliderParams(min:Number, max:Number, stepValue:Number=0):void
		{
			if((upBtn && sliderDist<upBtn.height) || min>=max || min<0){
				enabled = false;
				delEvt();
				return;
			}
			else
			{
				enabled = true;
				var slh:int = int(sliderDist*min/max);
				if(slh<MIN_SLIDER_HEIGHT) slh = int(THICKNESS);
				slider.height = slh;
				addEvt();
				this.visible = true;
			}
			
//			var stepValue:Number = step/(max-min);
			
			if(!stepValue) segment = scrollDist/25;
			else
				segment = (sliderDist-slh)*stepValue;
		}
		
		///////////////////////////////////
		// event handlers
		///////////////////////////////////
		
		/**
		 * 添加事件
		 */
		protected function addEvt():void
		{
			delEvt();	//防止多次添加事件，先清除再添加
			slider.addEventListener(MouseEvent.MOUSE_DOWN, onSliderDown);
			this.addEventListener(MouseEvent.MOUSE_DOWN,onDownClick);
		}
		
		/**
		 * 删除事件
		 */		
		protected function delEvt():void
		{
			this.removeEventListener(MouseEvent.MOUSE_DOWN, onDownClick);
			slider.removeEventListener(MouseEvent.MOUSE_DOWN, onSliderDown);
		}
		
		protected function onDownClick(e:MouseEvent):void
		{
			_clickTime = getTimer();
			_clickPosi = e.localY*((e.target==skinbg)?skinbg.scaleY:1);
			if(e.target == downBtn){
				_mouseUpDown = 0;
				upDownBtn();
			}
			else if(e.target == upBtn)
			{
				_mouseUpDown = 1;
				upDownBtn();
			}
			else if(e.target == skinbg)
			{
				_mouseUpDown = 2
				onMove(null);
			}
			if(_mouseUpDown>2 || !stage) return;
			stage.addEventListener(Event.ENTER_FRAME,onMove);
			stage.addEventListener(MouseEvent.MOUSE_UP,goUp);
			stage.addEventListener(Event.MOUSE_LEAVE,goUp);
//			onMoveSlider(null);
		}
		
		private function upDownBtn():void
		{
			if(!slider.visible){
				_value = _value - 0.05*(_mouseUpDown*2-1);
				onMoveSlider(null);
				return;
			}
			slider.y = slider.y - segment*(_mouseUpDown*2-1);
			if(!_mouseUpDown && (slider.y + segment)>sliderMaxY)
				slider.y = sliderMaxY;
//				slider.y = (THICKNESS + scrollDist);
			
			if(upBtn){
				if(_mouseUpDown==1 && (slider.y - segment)<upBtn.height)
					slider.y = upBtn.height;
			}else
				if(_mouseUpDown==1 && (slider.y - segment)<skinbg.y)
					slider.y = upBtn.height;
			
			onMoveSlider(null);
		}
		
		private function onMove(evt:Event):void
		{
			if(evt!=null && getTimer()<(_clickTime+DELAY_MOVE_TIME)) return;
			if(_mouseUpDown<2){
				upDownBtn();
				return;
			}
			if(_clickPosi>=slider.y && _clickPosi<=(slider.y + slider.height)){
				goUp(null);
				return;
			}
			if(_clickPosi>slider.y){
				var ey:int = slider.y + slider.height;
				var dis:int = style.height - (upBtn?upBtn.height:0) - slider.height;
				if(ey>dis) ey = dis;
				slider.y = ey;
			}else{
				ey = slider.y - slider.height;
				if(upBtn && ey<upBtn.height) ey = upBtn.height;
				if(!upBtn && ey<skinbg.y) ey = skinbg.y;
				slider.y = ey;
			}
			onMoveSlider(null);
		}
		
		private var _sliderMouseY:int;	//暂存鼠标点击相对滚动条中轴位置
		protected function onSliderDown(e:MouseEvent):void
		{
			_mouseUpDown = 3;
			_sliderMouseY = e.localY*slider.scaleY;
//			var rect:Rectangle = new Rectangle(0,upBtn.height,0,scrollDist);
//			slider.startDrag(false,rect);
			stage.addEventListener(MouseEvent.MOUSE_MOVE,onMoveSlider);
			stage.addEventListener(MouseEvent.MOUSE_UP,goUp);
			stage.addEventListener(Event.MOUSE_LEAVE,goUp);
		}
		
		// 滚动条y坐标有变化
		public function onMoveSlider(e:MouseEvent):void
		{
			if(e){
				var ly:int = upBtn?(upBtn.x+upBtn.height):skinbg.y;
				var ry:int = downBtn?(downBtn.y - slider.height):(skinbg.height - slider.height);
				
				if((mouseY - _sliderMouseY)<ly)
					slider.y = ly;
				else if((mouseY - _sliderMouseY)>ry)
					slider.y = ry;
				else slider.y = mouseY - _sliderMouseY;
			}
			
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		protected function goUp(e:Event):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMoveSlider);
			stage.removeEventListener(MouseEvent.MOUSE_UP,goUp);
			stage.removeEventListener(Event.MOUSE_LEAVE,goUp);
			stage.removeEventListener(Event.ENTER_FRAME,onMove);
//			slider.stopDrag();
		}
		
		///////////////////////////////////
		// getter/setters
		///////////////////////////////////
		
		override public function set enabled(value:Boolean):void
		{
			super.enabled = value;
			
			if(upBtn) upBtn.alpha = value ? 1.0 : 0.5;
			if(downBtn) downBtn.alpha = value ? 1.0 : 0.5;
			slider.visible = value;
		}
		
		/**
		 * 减掉上下箭头高的距离
		 */		
		protected function get sliderDist():int
		{
			if(skinbg && (!upBtn || !downBtn)) return style.height;
			return style.height - upBtn.height - downBtn.height;
		}
		
		/**
		 * 可滚动的距离
		 */		
		protected function get scrollDist():int
		{
			return sliderDist - slider.height;
		}
		
		/**
		 * slider的y坐标与可滚动高度距离的比值
		 */		
		public function get value():Number
		{
			if(slider.visible){
				if(upBtn)
					return (slider.y - upBtn.height)/scrollDist;
				else
					return slider.y/scrollDist;
			}
			else
				return _value;
		}
		
		// 中条能滚动的最大Y坐标
		public function get sliderMaxY():Number
		{
			if(downBtn)
				return downBtn.y - slider.height;
			else
				return skinbg.y - slider.height;
		}
		
		public function set value(v:Number):void
		{
			if(v>1) _value = 1;
			else if(v<0) _value = 0;
			else{
				_value = v;
			}
			var ty:int = upBtn?upBtn.width:skinbg.y;
			if(slider.visible) slider.y = ty + scrollDist*_value;
		}
		
		override protected function draw():void
		{
			super.draw();
			slider.y = (upBtn?upBtn.height:0) + scrollDist*_value;
		}
		
		override public function set height(value:Number):void
		{
//			skin.height = value;
			if(upBtn) upBtn.y		= 0;
			if(downBtn) downBtn.y	= value - downBtn.height;
			if(skinbg) skinbg.height = value;
			slider.y = (upBtn?upBtn.height:0) + scrollDist*_value;
			super.height = value;
		}
		
		override public function get width():Number
		{
			if(enabled) return style.width;
			else return 0;
		}
		
		
		override public function get height():Number
		{
			return style.height;
		}
		
/*		override public function destroy():void
		{
			super.destroy();
		}*/
		
		public function get upBtn():DisplayObject{ return skin.getChildByName("upBtn") as DisplayObject };
		public function get downBtn():DisplayObject{ return skin.getChildByName("downBtn") as DisplayObject };
		public function get slider():DisplayObject{ return skin.getChildByName("slider") as DisplayObject };
		public function get skinbg():DisplayObject{ return skin.getChildByName("skinbg") as DisplayObject };
	}
}